
/**
 * TypeScript 定义了三种保留元数据键，可获取运行时类型:
 * 1、类型元数据：使用元数据键 ”design:type”（用来获取属性类型）
 * 2、参数类型元数据：使用元数据键 ”design:paramtypes”（用来获取参数类型）
 * 3、返回值类型元数据：使用元数据键 ”design:returntype”（用来获取返回值类型）
 */

import { Injector } from "../injector/Injector";
import { INJECT_INFO_LIST_TAG } from "../typed/injector-typed";

/**
 * 注入Provider实例
 * @param default_provider
 * @param default_injector
 * @returns 
 */
export function inject(privider_name: string, default_injector?: Injector,): Function {
    return function (target: any, propertyName: string, index?: number): any {

        const injector: Injector = default_injector ? default_injector : Injector.default;

        // const typeWrapper = resolveToTypeWrapper(privider_name, target, propertyName, index);

        if (!Reflect.has(target, INJECT_INFO_LIST_TAG)) {
            Reflect.set(target, INJECT_INFO_LIST_TAG, []);
        }

        let injectInfoList = Reflect.get(target, INJECT_INFO_LIST_TAG);
        injectInfoList.push({
            // provider: provider, 
            injector: injector,
            propertyName: propertyName,
            index: index,
            value: (injector: Injector) => {
                // const lazyType = typeWrapper.lazyType();
                // if (lazyType === undefined || lazyType === Object) {
                //     throw new CannotInjectValueError(target as Constructor<unknown>, propertyName as string);
                // }

                return injector.getInstance(privider_name);
            }
        });

    };
}

export function inject2(target: Object, method: string | symbol, parameterIndex: number) {

    // CCClass.Attr.setClassAttr(target, propertyKey, 'inject', true);
};

/**
 * 装饰器  OnLoad时注入
 * 非InjectableComponent类需要装饰注入
 * @returns 
 */
export function injectOnLoad(): Function {

    return function (constructor: any) {
        let onFunc = constructor.prototype['onLoad'];
        constructor.prototype['onLoad'] = function () {

            Injector.injectObject(this);

            onFunc && onFunc.call(this);
        };

        // let offFunc = constructor.prototype['onDestroy'];
        // constructor.prototype['onDestroy'] = function () {
        //     offFunc && offFunc.call(this);
        // }
    };
}